# Copyright (c) 2018 Presto Labs Pte. Ltd.
# Author: leon

import hashlib

from tornado import gen
from urllib.parse import urlencode
from coin.exchange.okex_futures.types import OkexFuturesOrderSide
from coin.exchange.okex_futures.kr_rest import util
from coin.exchange.util.async_http_client import AsyncHttpClient


class OkexRestPrivate(object):
  def __init__(self,
               api_key,
               secret_key,
               timeout=30,
               *,
               order_timeout=30,
               http_client=None,
               max_connections=8):
    self._api_key = api_key
    self._secret_key = secret_key
    self._order_timeout = order_timeout
    self._timeout = timeout
    self._http_client = http_client or AsyncHttpClient(max_connections=max_connections)

  def _sign(self, param: dict):
    req_param = []
    for key in sorted(param.keys()):
      req_param.append('%s=%s' % (str(key), str(param[key])))
    req_param.append('secret_key=%s' % self._secret_key)
    req_str = '&'.join(req_param)
    return hashlib.md5(req_str.encode('utf-8')).hexdigest().upper()

  @gen.coroutine
  def userinfo(self):
    param = {'api_key': self._api_key}
    param['sign'] = self._sign(param)
    body = urlencode(param)
    response = yield self._http_client.post(
        'https://www.okex.com/api/v1/future_userinfo.do',
        headers={'Content-Type': 'application/x-www-form-urlencoded'},
        data=body,
        timeout=self._timeout)
    return response

  @gen.coroutine
  def trade(self,
            symbol: str,
            contract_type: str,
            future_order_side: OkexFuturesOrderSide,
            price: float,
            qty: float,
            lever_rate: int = 20):
    param = {
        'api_key': self._api_key,
        'symbol': symbol,
        'contract_type': contract_type,
        'price': util.fmt_price(price),
        'amount': '%d' % qty,
        'type': '%d' % future_order_side,
        'match_price': '0',
        'lever_rate': str(lever_rate)
    }
    param['sign'] = self._sign(param)
    body = urlencode(param)
    response = yield self._http_client.post(
        'https://www.okex.com/api/v1/future_trade.do',
        headers={'Content-Type': 'application/x-www-form-urlencoded'},
        data=body,
        timeout=self._order_timeout)
    return response

  @gen.coroutine
  def order_history(self, symbol, contract_type, working_order=True):
    param = {
        'api_key': self._api_key,
        'symbol': symbol,
        'contract_type': contract_type,
        'status': 1 if working_order else 2,
        'order_id': -1,
        'current_page': 1,
        'page_length': 50
    }
    param['sign'] = self._sign(param)
    body = urlencode(param)
    response = yield self._http_client.post(
        'https://www.okex.com/api/v1/future_order_info.do',
        headers={'Content-Type': 'application/x-www-form-urlencoded'},
        data=body,
        timeout=self._timeout)
    return response

  @gen.coroutine
  def position(self, symbol, contract_type):
    param = {'api_key': self._api_key, 'symbol': symbol, 'contract_type': contract_type}
    param['sign'] = self._sign(param)
    body = urlencode(param)
    response = yield self._http_client.post(
        'https://www.okex.com/api/v1/future_position.do',
        headers={'Content-Type': 'application/x-www-form-urlencoded'},
        data=body,
        timeout=self._timeout)
    return response
